﻿//tool.cpp

#include "tool.h"

const QString sysMain = "VCP";

QString getCurPath(void){
    QDir path(QDir::currentPath());
    retInfo(path.absolutePath());
    // if(path.baseName().toUpper()==sysMain){
    //     return QDir::currentPath();
    // }
    return QString("%0").arg(path.path());
}

QString getNumber(const float N,const int dec){
    return QString::number(N, 'f', dec);
}

bool saveImage(const QString name,int Dpi, int Rotate, QImage *img)
{
    QMatrix matrix;
    matrix.rotate(Rotate);

    bool ret;
    if(img != nullptr){
        img->setDotsPerMeterX(float(Dpi)*39.37);
        img->setDotsPerMeterY(float(Dpi)*39.37);
        if(Rotate != 0){
            *img = img->transformed(matrix);
        }
        ret = img->save(name);
    }else{
        QImage _img;
        _img.load(name);
        _img.setDotsPerMeterX(float(Dpi)*39.37);
        _img.setDotsPerMeterY(float(Dpi)*39.37);
        if(Rotate != 0){
            _img = _img.transformed(matrix);
        }
        ret = _img.save(name);
    }
//    qDebug()<<"save image " << name << "dpi=" << Dpi << "  ret=" << ret;
    return ret;
}

void retInfo(const QString msg)
{
    QTime curTime = QTime::currentTime();
    QString strTime = curTime.toString("hh:mm:ss.zzz");
    qDebug()<< strTime << msg;
}

//void retInfos(const QString msg, ...)
//{
//　　va_list arg_ptr;

//　　va_start(arg_ptr, i);
//　　j=va_arg(arg_ptr, int);
//　　va_end(arg_ptr);
//　　printf("%d %d/n", i, j);
//　　return;
//}

void qStrToCstr(const QString q_str,char *v_str,size_t size)
{
    QString s = q_str;

    QByteArray ba = s.toUtf8();
    memcpy((void *)v_str,ba.data(),size);
}

int qStrToInt(const QString q_str)
{
    return q_str.toInt();
}

float qStrToFloat(const QString q_str)
{
    return q_str.toFloat();
}

void qStrToInts(const QString q_str,int *v_ints,size_t size)
{
    QStringList tempList =  q_str.split(",");
    for (int index = 0;index < tempList.count(); index++) {
        if(index < (int)size){
            v_ints[index] = qStrToInt(tempList[index]);
        }
    }
}

cv::Mat cvMatInverse( const cv::Mat &inMat){
    int width = inMat.cols;
    int height = inMat.rows;
    int ch = inMat.channels();

    cv::Mat outMat;
    outMat = cv::Mat::zeros(cv::Size(width, height), inMat.type());

    for(int row=0;row<height;row++){
        for(int col=0;col<width;col++){
            if(ch == 3){
                cv::Vec3b pixel = inMat.at<cv::Vec3b>(row,col);
                for(int i=0;i<ch;i++){
                    outMat.at<cv::Vec3b>(row,col)[i] = 255 - pixel[i];
                }
            }
            if(ch == 1){
                uchar pixel = inMat.at<uchar>(row,col);
                outMat.at<uchar>(row,col) = 255 - pixel;
            }
        }
    }
    return outMat;
}

QImage  cvMatToQImage( const cv::Mat &inMat )
{
    switch ( inMat.type() )
    {
        // 8-bit, 4 channel
        case CV_8UC4:
        {
            QImage image( inMat.data,
                          inMat.cols, inMat.rows,
                          static_cast<int>(inMat.step),
                          QImage::Format_ARGB32 );

            return image;
        }
        // 8-bit, 3 channel
        case CV_8UC3:
        {
            QImage image( inMat.data,
                          inMat.cols, inMat.rows,
                          static_cast<int>(inMat.step),
                          QImage::Format_RGB888 );

            return image.rgbSwapped();
        }
        // 8-bit, 1 channel
        case CV_8UC1:
        {
            QImage image( inMat.data,
                          inMat.cols, inMat.rows,
                          static_cast<int>(inMat.step),
                          QImage::Format_Grayscale8 );
            return image;
        }
        default:
            retInfo(QString("CVS::cvMatToQImage() - cv::Mat image type not handled in switch: %0").arg(inMat.type()));
            break;
        }
        return QImage();
}

QPixmap cvMatToQPixmap( const cv::Mat &inMat )
{
    return QPixmap::fromImage( cvMatToQImage( inMat ));
}

cv::Mat matResize(const cv::Mat &image, int sWidth, int sHeight, float &scale){
    scale = imageScale(image.size().width,image.size().height,sWidth,sHeight);
    int w = int(image.size().width/scale);
    int h = int(image.size().height/scale);
    cv::Size dsize = cv::Size(w,h);
    cv::Mat result = cv::Mat(dsize, image.type());
//    //等比缩小
    cv::resize(image, result, dsize);
    return result;
}

float imageScale(int nWidth, int nHeight,int sWidth, int sHeight){
    float s1 = (float)nWidth/(float)sWidth;
    float s2 = (float)nHeight/(float)sHeight;
    return (s1 > s2) ? s1 : s2;
}

cv::Mat cvMatContrastBrightness(int contrastValue, int brightnessValue, const cv::Mat &inMat){
    double alpha = 1 + contrastValue*0.01;
    int beta = brightnessValue;
    // int ch = inMat.channels();

    cv::Mat outMat;

    inMat.convertTo(outMat, -1, alpha, beta);

    return outMat;
}


cv::Mat cvMatSaturation(int value, const cv::Mat &inMat){

    cv::Mat hsvMat, outMat;
    double staurationFactor = 1.0 + (double)value*0.01;
    //转换HSV色彩空间
    cv::cvtColor(inMat, hsvMat, cv::COLOR_BGR2HSV);
    //分离色彩通道
    std::vector<cv::Mat>hsvChannels;
    cv::split(hsvMat, hsvChannels);
    //调整饱和度
    hsvChannels[1] *= staurationFactor;
    //合并BGR色彩空间
    cv::merge(hsvChannels, hsvMat);
    //转回BGR色彩空间
    cv::cvtColor(hsvMat, outMat, cv::COLOR_HSV2BGR);
    return outMat;
}

cv::Mat cvMatGamma(int value, const cv::Mat &inMat){
    double gamma = cv::pow(2.0, (double)value/100.0);
    cv::Mat correctImage = cv::Mat::zeros(inMat.size(), inMat.type());

    cv::Mat clut(1, 256, CV_8U);
    for(int i=0;i<256;i++){
        clut.at<uchar>(i) = cv::saturate_cast<uchar>(cv::pow(i/255.0,gamma)*255.0);
    }
    cv::LUT(inMat, clut, correctImage);
    return correctImage;
}
